<template>
  <div class="login-container">
    <video
      class="video"
      muted
      src="../../assets/video/1.mp4"
      loop="loop"
      autoplay="true"
    ></video>
    <el-form
      :model="loginForm"
      status-icon
      :rules="rules"
      ref="loginForm"
      label-width="100px"
      class="demo-loginForm"
    >
      <h1 class="mz" v-text="title"></h1>
      <!--注册点击事件 开始是二维码角标  点击之后变成电脑角标 -->
      <i
        @click="(isErweiLogin = !isErweiLogin), (isSmsLogin = false)"
        :class="['jiaobiao', 'iconfont', jiaobiao]"
      >
      </i>
      <!-- 常规登录 -->
      <div class="common-login" v-if="!isErweiLogin && !isSmsLogin">
        <el-form-item label="用户名:" prop="username">
          <el-input
            type="text"
            v-model="loginForm.username"
            autocomplete="on"
          ></el-input>
        </el-form-item>
        <el-form-item label="密码:" prop="password">
          <el-input
            type="password"
            v-model="loginForm.password"
            autocomplete="off"
          ></el-input>
        </el-form-item>
        <el-form-item label="验证码" prop="captcha">
          <el-input
            maxlength="5"
            v-model="loginForm.captcha"
            class="captcha"
            ref="captcha"
            @keydown.native.enter="submitForm('loginForm')"
          ></el-input>
          <span class="captcha-svg" v-loading="loading">
            <i @click="updateCaptcha" v-html="captchaSvg"></i>
          </span>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="submitForm('loginForm')"
            >登录
          </el-button>
        </el-form-item>
        <!-- 手机登录图标按钮 -->
        <el-form-item>
          <div class="sms">
            <!-- 引入手机图标 -->
            <svg class="icon" aria-hidden="true">
              <use xlink:href="#icon-iphone"></use>
            </svg>
            <a
              href="javascript:;"
              @click="isSmsLogin = true"
              style="color: #fff; font-size: 16px"
            >
              切换短信登录
            </a>
          </div>
        </el-form-item>
      </div>

      <!-- 二维码登录 -->
      <div class="erwei" v-else-if="isErweiLogin && !isSmsLogin">
        <div class="img" v-loading="qrloading">
          <img :src="imgBase64Url" width="200px" />
          <i
            class="mask"
            :style="qrStyle"
            v-show="showQrMask"
            @click="getQrcode"
          ></i>
        </div>
        <p>
          <svg aria-hidden="true" class="icon-wx">
            <use xlink:href="#icon-weixin"></use>
          </svg>
          <i v-text="qrTip"></i>
        </p>
      </div>

      <!-- 短信验证码登录 -->
      <div class="smsContainer" v-else>
        <el-form-item label="手机号">
          <el-input
            maxlength="11"
            v-model="phoneNumber"
            class="captcha phone"
          ></el-input>
          <span
            @click="sendSmsCode"
            class="captcha-svg"
            v-text="smsRetryMsg"
            style="color: #888; line-height: 45px; text-decoration: underline"
          >
          </span>
        </el-form-item>
        <el-form-item label="验证码">
          <el-input v-model="smsCode" @keydown.native.enter="smaSubmit" ></el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="smaSubmit">登录</el-button>
        </el-form-item>
      </div>
    </el-form>
  </div>
</template>
<script>
//引入api中的方法
import * as api from "@/api/users";
//引入socket
import socketIo from "socket.io-client";

//引入生成二维码的插件qrcode
import qr from "qrcode";

//引入扫码成功和失效的图片
import scancodeSuccessPic from "../../assets/img/scancode.png";
import invalidPic from "../../assets/img/invalidQr.png";

//映射vuex
import { mapMutations } from "vuex";

//效验验证码
var validateCaptcha = (rule, value, callback) => {
  if (!value) {
    callback("传入验证码");
  } else {
    callback();
  }
};
//用户名效验函数
var validateUsername = (rule, value, callback) => {
  let pattern = /^[a-zA-Z0-9_-]{4,16}$/;
  if (pattern.test(value)) {
    callback(); //不传参就是通过
  } else {
    callback("4到16位(字母,数字,下划线,减号)");
  }
};
//密码效验函数
var validatePassword = (rule, value, callback) => {
  if (value === "") {
    callback(new Error("请输入密码"));
  } else {
    callback();
  }
};
export default {
  name: "login",
  data() {
    return {
      smsDisabled: false, //控制是否能够再次发送
      captchaSvg: "", //验证码svg
      loading: true, //加载动画布尔值
      isErweiLogin: false, //是否是二维码登录
      isSmsLogin: false, //短信登入
      title: "万锋管理系统",
      smsCode: "",
      qrTip: "请使用微信扫码登入",
      showQrMask: false, //是否显示二维码遮罩
      qrloading: true, //加载二维码动画
      phoneNumber: "", //xx多少秒之后重新发送提示
      smsRetryMsg: "点击发送验证码",
      loginForm: {
        username: "",
        password: "",
        captcha: "",
      },
      rules: {
        username: [{ validator: validateUsername, trigger: "blur" }],
        password: [{ validator: validatePassword, trigger: "blur" }],
        captcha: [{ validator: validateCaptcha, trigger: "blur" }],
      },
      imgBase64Url: "", //二维码base64的图片地址
      isScanCodeSuccess: false, //是否扫码成功
      qrStyle: {
        backgroundImage: `url(${invalidPic})`,
      },
    };
  },
  created() {
    //调用获取验证码的方法
    this.updateCaptcha();
  },
  //计算属性
  computed: {
    jiaobiao() {
      return this.isErweiLogin
        ? "icon-diannaojiaobiao"
        : "icon-erweimajiaobiao";
    },
  },
  watch: {
    //监听切换短信登入逻辑
    isSmsLogin(val) {
      //不是短信登入的时候清除定时器
      if (!val) {
        if (this.smsInterval) {
          clearInterval(this.smsInterval);
        }
        //将短信登入的文字提示回复
        this.smsRetryMsg = "点击发送验证码";
      }
    },

    //监听切换二维码登入的字段
    isErweiLogin(isErwei) {
      if (isErwei) {
        //切换了二维码页面
        //打开二维码加载动画
        this.qrloading = true;
        // 需要把遮罩关掉
        this.showQrMask = false;
        //建立socket 连接
        //https协议，要使用wss协议
        let io = socketIo("wss://chst.vip");
        //扫码成功
        io.on("scancodeSuccess", async (data) => {
          //显示二维码的遮罩 并且将背景图片换成扫码成功的背景图片
          this.showQrMask = true;
          this.qrStyle.backgroundImage = `url(${scancodeSuccessPic})`;
          // console.log(data);
          //先结构内容
          let { state: scanCodeState, wechatCode } = data;
          // console.log(scanCodeState)
          if (scanCodeState) {
            //扫码成功了
            let scanCodeRes = await api.wechatLogin(wechatCode);
            // console.log(scanCodeRes);
            //结构内容
            let {
              state,
              userInfo,
              permission: { buttons },
              token,
            } = scanCodeRes.data;
            //把token userInfo permissions 存储到本地
            if (state) {
              localStorage.setItem("wf-userInfo", JSON.stringify(userInfo));
              localStorage.setItem("wf-permissionBtn", JSON.stringify(buttons));
              localStorage.setItem("wf-token", token);
                 //调用vuex方法  设置用户信息
                this.SET_USERINFO(userInfo)
              //跳转到欢迎页
              this.$router.push("/");
              //关闭二维码遮罩
              this.showQrMask = false;
            }
          }
        });
        // 二维码失效
        io.on("invalidCode", (data) => {
          // console.log(data);
          let { state } = data;
          if (!state) {
            // 扫码失效
            this.showQrMask = true;
            //将提示文字变更
            this.qrTip = "二维码失效,请重新点击获取二维码";
          }
        });
        //连接成功
        io.on("connectSuccess", async (data) => {
          // console.log(data);
          //从data中结构出sid
          let { sid } = data;
          //唯一标识存到本地
          localStorage.setItem("wf-sid", sid);
          //调用获取二维码的方法
          this.getQrcode(sid);
        });
      }
    },
  },
  methods: {

    //映射vuex的Mutation
    ...mapMutations(['SET_USERINFO']),

    submitForm(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          alert("通过");
        } else {
          alert("不通过");
        }
      });
    },
    //短信验证码登录
    async smaSubmit() {
      let smsLoginRes = await api.smsLogin(this.smsCode);
      console.log(smsLoginRes);
      //判断登入状态 如果登入成功将数据存储到本地
      //结构赋值
      let {
        userInfo,
        state,
        permission: { buttons },
        token,
      } = smsLoginRes.data;
      //把token userInfo permissions 存储到本地
      if (state) {
        // localStorage.setItem("wf-userInfo", JSON.stringify(userInfo));
        localStorage.setItem("wf-permissionBtn", JSON.stringify(buttons));
        localStorage.setItem("wf-token", token);
         //调用vuex方法  设置用户信息
          this.SET_USERINFO(userInfo)

        //跳转到欢迎页
        this.$router.push("/")
      }
    },
    //封装短信登入相关的方法
    async sendSmsCode() {
      // 判断一下是否可以发送短信 通过smsDisabled来控制
      if (this.smsDisabled) {
        this.$message.error("一分钟内只能发送一次");
        return; // 后面的逻辑不执行
      }
      // console.log(this.phoneNumber)
      //获取手机号 传递给后台 调用发送短信的接口
      let smsResult = await api.getSmsCode(this.phoneNumber);
      //结构内容
      let { state } = smsResult.data;
      if (state) {
        //锁住smsDisabled 不能再发送了
        this.smsDisabled = true;
        //提示用户短信发送成功
        this.$message.success("短信发送成功");
        this.smsSecond = 60;
        //短信发送需要进入倒计时
        this.smsInterval = setInterval(() => {
          this.smsSecond--;
          if (this.smsSecond === 0) {
            //清掉定时器
            clearInterval(this.smsInterval);
            this.smsRetryMsg = "点击发送验证码";
            //解锁smsDisabled 可以继续发送短信了
            this.smsDisabled = false;
            return;
          }
          this.smsRetryMsg = `${this.smsSecond}秒后重新发送`;
        }, 1000);
      }
      console.log(smsResult);
    },
    //封装一个获取二维码地址的方法
    async getQrcode(sid) {
      //将文字提示变更
      this.qrTip = "请使用微信扫码登入";
      //先关掉遮罩
      this.showQrMask = false;
      //把加载二维码动画打开
      this.qrloading = true;
      //双问号  如果没有获取到前面 就会用后面的
      sid = localStorage.getItem("wf-sid") ?? sid;
      //调用接口获取二维码url
      let qrResult = await api.getQrcode(sid);
      // console.log(qrResult);
      //结构 scanCodeUrl 和 后端的状态
      let { scanCodeUrl, state: getQrState } = qrResult.data;

      //判断服务器状态
      if (getQrState) {
        //如果成功
        //使用qrcode 插件 将scanCodeUrl变成一个二维码
        qr.toDataURL(scanCodeUrl, (err, imgBase64Url) => {
          if (err) {
            this.$messageBox.error(err);
            return;
          }
          // console.log(imgBase64Url);
          this.imgBase64Url = imgBase64Url;
          //关闭二维码加载动画
          this.qrloading = false;
        });
      }
    },
    // //封装一个方法,专门用于获取验证码
    updateCaptcha() {
      //打开加载动画
      this.loading = true;
      api.getCaptcha().then((res) => {
        // console.log(res);
        let { img } = res.data; //解构验证码
        this.captchaSvg = img;
        //关闭加载动画
        this.loading = false;
      });
    },
    //常规登入
    async submitForm(formName) {
      //登录逻辑
      //1 先要进行本地的表单效验
      //2 表单效验通过之后 通过v-model获取输入的username password
      //3 效验验证码
      //4 效验通过之后 发起请求 请求登入接口 传入用户名和密码
      //5 跳转到主页显示主页

      //fromName是表单的ref名字
      // console.log(this.$refs);
      this.$refs[formName].validate((valid) => {
        // console.log(valid);
        if (valid) {
          //打开加载动画
          const loading = this.$loading({
            lock: true,
            text: "正在登入",
            spinner: "el-icon-loading",
            background: "rgba(0,0,0,0.7)",
          });

          //本地表单效验通过
          let { username, password, captcha } = this.loginForm;
          //效验验证码  调取方法
          api.verifyCaptcha(captcha).then(async (res) => {
            // console.log(res);
            let { state } = res.data; //解析返回的结构
            if (state) {
              //验证码正确
              let loginRes = await api.login(username, password);
              // console.log(loginRes);
              let { state: loginState, msg, token, userInfo } = loginRes.data;
              if (loginState) {
                //关闭登入加载动画
                loading.close();

                //将token存到localStorage
                localStorage.setItem("wf-token", token);

              //调用vuex方法  设置用户信息
                this.SET_USERINFO(userInfo)
                //登入成功了  页面就跳转
                this.$router.push("/");
                //提示登录成功
                this.$message({
                  message: msg,
                  type: "success",
                  duration: 1000,
                });
              } else {
                //登录失败 关闭loading
                loading.close();
              }
            } else {
              //登录失败 关闭loading
              loading.close();
              //刷新验证码
              this.updateCaptcha()
            }
          });
        } else {
          //表单效验不通过
        }
      });
    },
  },
};
</script>

<style lang="less" scoped>
//1 找类名
//2 看权重
//3 看是否需要深度选择器

.login-container {
  text-align: center;
  color: #fff;

  .video {
    position: fixed;
    left: 0px;
    top: 0px;
    right: 0px;
    bottom: 0px;
  }

  .mz {
    text-align: center;
    margin: 0 0 50px 0;
    color: #fff;
  }
}

.el-input {
  position: relative;
  font-size: 14px;
  display: inline-block;
  width: 100%;
  /deep/ .el-input__inner {
    width: 300px !important;
  }
}
.el-form-item__content {
  .el-button {
    width: 300px !important;
  }
}
.el-form {
  // position: absolute !important;
  // top:80px !important;
  height: 400px;
  position: fixed;
  right: 35%;
  top: 20%;
  border-radius: 5px;
  width: 400px;
  background-color: rgba(0, 0, 0, 0.3);
  padding: 100px 0 50px 0;
}

.el-form-item {
  position: relative;
  right: 30px !important;
}
/deep/ .el-form-item__label {
  color: #fff !important;
}
.captcha {
  // width:30px;
  // height:100px;
  // vertical-align: top;
}
.captcha-svg {
  background: #fff;
  display: inline-block;
  height: 36px;
  width: 150px;
  text-align: center;
  cursor: pointer;
  border: 0;
  border-radius: 0 5px 5px 0;
  position: absolute;
  right: -47px;
}
.jiaobiao {
  font-size: 60px;
  color: #fff;
  position: absolute;
  right: -1px;
  top: -1px;
  cursor: pointer;
  opacity: 0.7;
}
.sms {
  .icon {
    width: 2em;
    height: 2em;
    vertical-align: middle;
    fill: currentColor;
    overflow: hidden;
  }
}
.smsContainer {
  padding-right: 20px !important;
  width: 50%;

  /deep/ .el-form-item__label {
    // margin-left: 80px !important
    padding: 0 !important;
    padding-right: 10px !important;
  }

  /deep/ .phone {
    width: 140px !important;
  }

  /deep/ .captcha-svg {
    position: absolute;
    left: 184px;
    bottom: 3px;
    width: 115px !important;
  }

  /deep/ .el-form-item__content {
    margin: 0;
  }
}

.icon-wx {
  width: 25px !important;
  height: 25px !important;
  vertical-align: -7px;
  margin-right: 3px;
}

.common-login {
  padding-right: 50px;
}

// 二维码样式
.erwei .img {
  display: inline-block;
  position: relative;
  width: 200px;
  height: 200px;

  img {
    position: absolute;
    left: 0;
  }

  .mask {
    width: 100%;
    height: 100%;
    opacity: 0.8;
    background-color: #fff;
    position: absolute;
    left: 0;
    background-size: 50%;
    background-repeat: no-repeat;
    background-position: center;
    cursor: pointer;
  }
}
</style>
